package org.kl.bf.web.basic;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.io.FileUtils;
import org.joda.time.DateTime;
import org.kl.bf.entity.AttachInfo;
import org.kl.bf.entity.basic.Attachment;
import org.kl.bf.entity.basic.AttachmentMaster;
import org.kl.bf.entity.easyui.EasyuiGrid;
import org.kl.bf.service.basic.AttachmentMasterService;
import org.kl.bf.service.basic.AttachmentService;
import org.kl.bf.utils.BasicConstants;
import org.kl.bf.web.base.BasicController;
import org.kl.auditsupervision.utils.AuditsupervisionConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.modules.web.MediaTypes;
import org.springside.modules.web.Servlets;

/**
 * 
 * @author QJ
 * @date 2014年9月9日
 */
@Controller
@RequestMapping(value = "/basic/attachment")
public class AttachmentController extends BasicController {

	@Autowired
	private AttachmentService attachmentService;

	@Autowired
	private AttachmentMasterService attachmentMasterService;
	

	@RequestMapping(method = RequestMethod.GET)
	public String list() {
		return "basic/attachmentList";
	}

	@RequestMapping(value = "update", method = RequestMethod.POST)
	@ResponseBody
	public String update(
			@Valid @ModelAttribute("attachment") Attachment attachment,
			RedirectAttributes redirectAttributes) {
		try {
			attachmentService.saveAttachment(attachment);
			return ajaxMsg("编辑成功", true, null);
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("编辑失败" + e.getMessage(), false, null);
		}
	}

	/**
	 * 删除附件
	 * 
	 * @param id
	 * @param redirectAttributes
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "delete/{id}", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String delete(@PathVariable("id") String id,
			RedirectAttributes redirectAttributes, HttpServletRequest request) {
		try {
			boolean result = attachmentService.deleteAttachment(id, "删除");
			if (result) {
				return ajaxMsg("删除成功", true, null);
			} else {
				return ajaxMsg("删除失败", false, null);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("删除失败", false, null);
		}
	}

	//通用上传单个相片
	@RequestMapping(value = "upload",produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String upload(HttpServletRequest request,
			HttpServletResponse response) {
		String responseStr = "";
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
		String ctxPath = (String) request.getSession().getServletContext()
				.getAttribute(BasicConstants.CONFIG_UPLOADPATH);
		if (StringUtils.isEmpty(ctxPath)) {
			ctxPath = AuditsupervisionConstants.UPLOAD_PATH;
		}
		// 创建文件夹
		File file = new File(ctxPath);
		if (!file.exists()) {
			file.mkdirs();
		}
		String fileName = null;
		Attachment a = new Attachment();
		for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
			// 上传文件名
			MultipartFile mf = entity.getValue();
			fileName = mf.getOriginalFilename();
			String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1)
					.toLowerCase();

			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
			String newFileName = df.format(new Date()) + "_"
					+ new Random().nextInt(1000) + "." + fileExt;
			File uploadFile = new File(ctxPath + newFileName);
			try {
				FileCopyUtils.copy(mf.getBytes(), uploadFile);
				responseStr = "上传成功";
				a.setFileName(fileName);
				a.setFilePath(uploadFile.getAbsolutePath());
				a.setFileSize(uploadFile.length() + "");
				a.setUploadTime(new Date());
				a.setUploadUserId(getCurrentUserId());
				attachmentService.saveAttachment(a);
				String attachmentId=a.getId();
				request.getSession().setAttribute("attachmentId",attachmentId);
			} catch (IOException e) {
				responseStr = "上传失败";
				e.printStackTrace();
			}
		}
		return ajaxMsg(responseStr, true, a);
	}	

	/**
	 * 文件下载
	 * 
	 * @author QJ
	 * @param response
	 * @param request
	 * @param realName
	 * @param name
	 */
	@RequestMapping("/download/{attachId}")
	public void download(HttpServletResponse response,
			HttpServletRequest request,
			@PathVariable("attachId") String attachId) {
		OutputStream os = null;
		response.reset();
		Attachment a = attachmentService.getAttachment(attachId);
		try {
			response.setHeader(
					"Content-Disposition",
					(new StringBuilder("attachment; filename=")).append(
							new String(a.getFileName().getBytes("GBK"),
									"iso8859-1")).toString());// 解决中文乱码问题
			response.setContentType("application/octet-stream; charset=utf-8");
			os = response.getOutputStream();
			os.write(FileUtils.readFileToByteArray(new File(a.getFilePath())));
			os.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * excel导入错误文件下载
	 * @author QJ
	 * @param response
	 * @param request
	 * @param realName
	 * @param name
	 */
	@RequestMapping("/xlsErrTemp/{xlsName}")
	public void xlsErrTemp(HttpServletResponse response,
			HttpServletRequest request,
			@PathVariable("xlsName") String xlsName) {
		OutputStream os = null;
		response.reset();
		String fileName = xlsName+".xls";
		try {
			response.setHeader(
					"Content-Disposition",
					(new StringBuilder("attachment; filename=")).append(
							new String(fileName.getBytes("GBK"),
									"iso8859-1")).toString());// 解决中文乱码问题
			response.setContentType("application/octet-stream; charset=utf-8");
			os = response.getOutputStream();
			os.write(FileUtils.readFileToByteArray(new File(BasicConstants.EXCEL_ERROR_FOLDER+File.separator+fileName)));
			os.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 获取附件列表,通过附件主表Id获取
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @param sortType
	 * @param orderType
	 * @param model
	 * @param request
	 * @param masterId
	 *            附件主表Id
	 * @return
	 */
	@RequestMapping(value = "dataGrid/{masterId}", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String dataGrid(
			@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
			@RequestParam(value = "rows", defaultValue = PAGE_SIZE) int pageSize,
			@RequestParam(value = "sort", defaultValue = "id") String sortType,
			@RequestParam(value = "order", defaultValue = "desc") String orderType,
			Model model, ServletRequest request,
			@PathVariable("masterId") String masterId,
			@RequestParam(value = "attachmentType", defaultValue = "") String attachmentType) {
		try {
			Map<String, Object> searchParams = Servlets
					.getParametersStartingWith(request, SEARCH_PREFIX);
			searchParams.put("EQ_attachmentMasterId", masterId);
			if(!StringUtils.isEmpty(attachmentType)){
				searchParams.put("EQ_attachmentType", attachmentType);
			}
			Page<Attachment> attachments = attachmentService.getAttachment(
					searchParams, pageNumber, pageSize, sortType, orderType);
			EasyuiGrid grid = new EasyuiGrid();
			grid.setRows(attachments.getContent());
			grid.setTotal((int) attachments.getTotalElements());
			String result = jsonMapper.toJson(grid);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("数据加载失败" + e.getMessage(), false, null);
		}
	}

	/**
	 * 上传附件。
	 * @param request
	 * @param response
	 * @param attachMaster
	 * @return
	 */
	@RequestMapping(value = "busUpload/{masterId}", produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String busUpload(HttpServletRequest request,
			HttpServletResponse response,
			@PathVariable("masterId") String masterId,
			@RequestParam(value = "attachmentType", defaultValue = "") String attachmentType) {
		AttachmentMaster attachMaster = attachmentMasterService
				.getAttachmentMaster(masterId);
		if (attachMaster == null) {
			return ajaxMsg("上传失败", false, null);
		} else {
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
			// 文件保存路径
			String ctxPath = (String) request.getSession().getServletContext()
					.getAttribute(BasicConstants.CONFIG_UPLOADPATH);
			if (StringUtils.isEmpty(ctxPath)) {
				ctxPath = AuditsupervisionConstants.UPLOAD_PATH;
			}
			ctxPath += File.separator + attachMaster.getLevelType1()
					+ File.separator + attachMaster.getLevelType2()
					+ File.separator;
			// 创建文件夹
			File file = new File(ctxPath);
			if (!file.exists()) {
				file.mkdirs();
			}
			String fileName = null;
			try {
				List<Attachment> attachments = attachMaster.getAttachmentList();
				if (attachments == null) {
					attachments = new ArrayList<Attachment>();
					attachMaster.setAttachmentList(attachments);
				}
				for (Map.Entry<String, MultipartFile> entity : fileMap
						.entrySet()) {
					// 上传文件
					MultipartFile mf = entity.getValue();
					fileName = mf.getOriginalFilename();
					String fileExt = fileName.substring(
							fileName.lastIndexOf(".") + 1).toLowerCase();
					// 重命名文件
					String filePath = ctxPath
							+ new DateTime().toString("yyyyMMddHHmmss")
							+ new Random().nextInt(1000) + "." + fileExt;
					File uploadFile = new File(filePath);
					FileCopyUtils.copy(mf.getBytes(), uploadFile);
					// 写数据库信息
					Attachment attachment = new Attachment();
					attachment.setFileName(fileName);
					attachment.setFilePath(filePath);
					attachment.setFileSize(mf.getSize() + "");
					attachment.setUploadTime(new Date());
					attachment.setUploadUserId(getCurrentUserId());
					attachment.setAttachmentMasterId(attachMaster.getId());
					attachmentType=java.net.URLDecoder.decode(attachmentType, "UTF-8");
					attachment.setAttachmentType(attachmentType);
					attachmentService.saveAttachment(attachment);
					attachments.add(attachment);
				}
				attachmentMasterService.saveAttachmentMaster(attachMaster);
				return ajaxMsg("上传成功!", true, null);
			} catch (IOException e) {
				e.printStackTrace();
				return ajaxMsg("上传失败!" + e.getMessage(), false, null);
			}
		}
	}

	/**
	 * 上传附件，限定单个附件
	 * 
	 * @param request
	 * @param response
	 * @param attachMaster
	 * @return
	 */
	@RequestMapping(value = "busUpload/single/{masterId}", produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String busUploadSingle(HttpServletRequest request,
			HttpServletResponse response,
			@PathVariable("masterId") String masterId) {
		AttachmentMaster attachMaster = attachmentMasterService
				.getAttachmentMaster(masterId);
		if (attachMaster == null) {
			return ajaxMsg("上传失败", false, null);
		} else {
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
			// 文件保存路径
			String ctxPath = (String) request.getSession().getServletContext()
					.getAttribute(BasicConstants.CONFIG_UPLOADPATH);
			if (StringUtils.isEmpty(ctxPath)) {
				ctxPath = AuditsupervisionConstants.UPLOAD_PATH;
			}
			ctxPath += File.separator + attachMaster.getLevelType1()
					+ File.separator + attachMaster.getLevelType2()
					+ File.separator;
			// 创建文件夹
			File file = new File(ctxPath);
			if (!file.exists()) {
				file.mkdirs();
			}
			String fileName = null;
			try {
				List<Attachment> attachments = attachMaster.getAttachmentList();
				if (attachments == null) {
					attachments = new ArrayList<Attachment>();
					attachMaster.setAttachmentList(attachments);
				}
				for (Map.Entry<String, MultipartFile> entity : fileMap
						.entrySet()) {
					// 上传文件
					MultipartFile mf = entity.getValue();
					fileName = mf.getOriginalFilename();
					String fileExt = fileName.substring(
							fileName.lastIndexOf(".") + 1).toLowerCase();
					// 重命名文件
					String filePath = ctxPath
							+ new DateTime().toString("yyyyMMddHHmmss")
							+ new Random().nextInt(1000) + "." + fileExt;
					File uploadFile = new File(filePath);
					FileCopyUtils.copy(mf.getBytes(), uploadFile);
					// 写数据库信息
					// 1.将原来的附件放入回收站
					if (attachMaster.getAttachmentList().size() > 0) {
						Attachment attachment = (Attachment) attachMaster
								.getAttachmentList().get(0);
						attachmentService.deleteAttachment(attachment.getId(), "覆盖");
					}
					// 2.插入新附件
					Attachment attachment = new Attachment();
					attachment.setFileName(fileName);
					attachment.setFilePath(filePath);
					attachment.setFileSize(mf.getSize() + "");
					attachment.setUploadTime(new Date());
					attachment.setUploadUserId(getCurrentUserId());
					attachment.setAttachmentMasterId(attachMaster.getId());
					attachmentService.saveAttachment(attachment);
					attachments.add(attachment);
				}
				attachmentMasterService.saveAttachmentMaster(attachMaster);
				return ajaxMsg("上传成功!", true, null);
			} catch (IOException e) {
				e.printStackTrace();
				return ajaxMsg("上传失败!" + e.getMessage(), false, null);
			}
		}
	}
	
	/**
	 * 可进行多附件、单附件上传
	 */
	@RequestMapping(value = "multiUpload/{masterId}", produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String multiUpload(HttpServletRequest request, HttpServletResponse response, @PathVariable("masterId") String masterId) {
		AttachmentMaster attachMaster = attachmentMasterService.getAttachmentMaster(masterId);
		if (attachMaster == null) {
			return ajaxMsg("上传失败", false, null);
		} else {
			String responseStr = "上传失败";
			MultipartHttpServletRequest multipartreRequest = (MultipartHttpServletRequest) request;
			Iterator<String> iter = multipartreRequest.getFileNames();
			List<Attachment> attachments = attachMaster.getAttachmentList();
			while (iter.hasNext()) {
				MultipartFile file = multipartreRequest.getFile(iter.next());
				String fileName = null;
				String ctxPath = AuditsupervisionConstants.UPLOAD_PATH;
				File ctxFile = new File(ctxPath);
				if (!ctxFile.exists()) {
					ctxFile.mkdirs();
				}
				Attachment attachment = new Attachment();
				if (file.getSize() > 0) {
					fileName = file.getOriginalFilename();
					String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
					SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
					String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
					String filePath = ctxPath + "\\" + newFileName;
					File localFile = new File(filePath);
					try {
						file.transferTo(localFile);
						responseStr = "上传成功";
						attachment.setFileName(fileName);
						attachment.setFilePath(localFile.getAbsolutePath());
						attachment.setFileSize(localFile.length() + "");
						attachment.setUploadTime(new Date());
						attachment.setUploadUserId(getCurrentUserId());
						attachment.setAttachmentMasterId(attachMaster.getId());
						attachmentService.saveAttachment(attachment);
						attachments.add(attachment);
					} catch (Exception e) {
						responseStr = "上传失败";
						e.printStackTrace();
					}
				}
			}
			attachmentMasterService.saveAttachmentMaster(attachMaster);
			return ajaxMsg(responseStr, true, null);
		}
	}
	
	/**
	 * 行编辑保存附件信息
	 * @param attachUpdated
	 * @param result
	 * @return
	 */
	@RequestMapping(value = "crud", method = RequestMethod.POST)
	@ResponseBody
	public String crud(@RequestParam(value = "attachUpdated", required = false) String attachUpdated, RedirectAttributes redirectAttributes) {
		try {
			attachmentService.save(attachUpdated);
			return ajaxMsg("保存成功", true, null);
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("保存失败:" + e.getMessage(), false, null);
		}
	}

	/**
	 * 通用的附件上传页面
	 * 
	 * @author QJ
	 * @param masterId
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "attachList/{masterId}")
	public String attachList(@PathVariable("masterId") String masterId,@RequestParam(value = "flag", defaultValue = "true") String flag,
			Model model) {
		AttachmentMaster attachMaster = attachmentMasterService
				.getAttachmentMaster(masterId);
		AttachInfo attachInfo = new AttachInfo();
		attachInfo.setMasterId(masterId);
		attachInfo.setTitle(attachMaster.getLevelType1() + ">>"
				+ attachMaster.getLevelType2() + ">>"
				+ attachMaster.getBusinessCode());
		model.addAttribute("attachInfo", attachInfo);
		model.addAttribute("flag", flag);//附件上传页面（flag标志控制页面附件能否被删除）
		return "pub/attachList";
	}

	/**
	 * 通用的附件查看页面
	 * 
	 * @author QJ
	 * @param masterId
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "attachView/{masterId}")
	public String attachView(@PathVariable("masterId") String masterId,
			Model model) {
		AttachmentMaster attachMaster = attachmentMasterService
				.getAttachmentMaster(masterId);
		AttachInfo attachInfo = new AttachInfo();
		attachInfo.setMasterId(masterId);
		attachInfo.setTitle(attachMaster.getLevelType1() + ">>"
				+ attachMaster.getLevelType2() + ">>"
				+ attachMaster.getBusinessCode());
		model.addAttribute("attachInfo", attachInfo);
		return "pub/attachView";
	}
	
	/**
	 * 所有RequestMapping方法调用前的Model准备方法, 实现Struts2
	 * Preparable二次部分绑定的效果,先根据form的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
	 * 因为仅update()方法的form中有id属性，因此仅在update时实际执行.
	 */
	@ModelAttribute
	public void getAttachment(@RequestParam(value = "id", defaultValue = "-1") String id,Model model) {
		if (!id.equals("-1")) {model.addAttribute("attachment",attachmentService.getAttachment(id));
		}
	}

}